package co.edu.udistrital;

import java.awt.Color;

/**
 *
 */
public enum Figura {

	/**
	 * Figura I.
	 */
	TypeI(new Color(Tablero.COLOR_MIN, Tablero.COLOR_MAX, Tablero.COLOR_MAX), 4, 4, 1, new boolean[][] {
		{
			false,	false,	false,	false,
			true,	true,	true,	true,
			false,	false,	false,	false,
			false,	false,	false,	false,
		},
		{
			false,	false,	true,	false,
			false,	false,	true,	false,
			false,	false,	true,	false,
			false,	false,	true,	false,
		},
		{
			false,	false,	false,	false,
			false,	false,	false,	false,
			true,	true,	true,	true,
			false,	false,	false,	false,
		},
		{
			false,	true,	false,	false,
			false,	true,	false,	false,
			false,	true,	false,	false,
			false,	true,	false,	false,
		}
	}),
	
	/**
	 * Figura J
	 */
	TypeJ(new Color(Tablero.COLOR_MIN, Tablero.COLOR_MIN, Tablero.COLOR_MAX), 3, 3, 2, new boolean[][] {
		{
			true,	false,	false,
			true,	true,	true,
			false,	false,	false,
		},
		{
			false,	true,	true,
			false,	true,	false,
			false,	true,	false,
		},
		{
			false,	false,	false,
			true,	true,	true,
			false,	false,	true,
		},
		{
			false,	true,	false,
			false,	true,	false,
			true,	true,	false,
		}
	}),
	
	/**
	 * Figura L
	 */
	TypeL(new Color(Tablero.COLOR_MAX, 127, Tablero.COLOR_MIN), 3, 3, 2, new boolean[][] {
		{
			false,	false,	true,
			true,	true,	true,
			false,	false,	false,
		},
		{
			false,	true,	false,
			false,	true,	false,
			false,	true,	true,
		},
		{
			false,	false,	false,
			true,	true,	true,
			true,	false,	false,
		},
		{
			true,	true,	false,
			false,	true,	false,
			false,	true,	false,
		}
	}),
	
	/**
	 * Figura O.
	 */
	TypeO(new Color(Tablero.COLOR_MAX, Tablero.COLOR_MAX, Tablero.COLOR_MIN), 2, 2, 2, new boolean[][] {
		{
			true,	true,
			true,	true,
		},
		{
			true,	true,
			true,	true,
		},
		{	
			true,	true,
			true,	true,
		},
		{
			true,	true,
			true,	true,
		}
	}),
	
	/**
	 * Figura S.
	 */
	TypeS(new Color(Tablero.COLOR_MIN, Tablero.COLOR_MAX, Tablero.COLOR_MIN), 3, 3, 2, new boolean[][] {
		{
			false,	true,	true,
			true,	true,	false,
			false,	false,	false,
		},
		{
			false,	true,	false,
			false,	true,	true,
			false,	false,	true,
		},
		{
			false,	false,	false,
			false,	true,	true,
			true,	true,	false,
		},
		{
			true,	false,	false,
			true,	true,	false,
			false,	true,	false,
		}
	}),
	
	/**
	 * Figura T
	 */
	TypeT(new Color(128, Tablero.COLOR_MIN, 128), 3, 3, 2, new boolean[][] {
		{
			false,	true,	false,
			true,	true,	true,
			false,	false,	false,
		},
		{
			false,	true,	false,
			false,	true,	true,
			false,	true,	false,
		},
		{
			false,	false,	false,
			true,	true,	true,
			false,	true,	false,
		},
		{
			false,	true,	false,
			true,	true,	false,
			false,	true,	false,
		}
	}),
	
	/**
	 * Figura Z
	 */
	TypeZ(new Color(Tablero.COLOR_MAX, Tablero.COLOR_MIN, Tablero.COLOR_MIN), 3, 3, 2, new boolean[][] {
		{
			true,	true,	false,
			false,	true,	true,
			false,	false,	false,
		},
		{
			false,	false,	true,
			false,	true,	true,
			false,	true,	false,
		},
		{
			false,	false,	false,
			true,	true,	false,
			false,	true,	true,
		},
		{
			false,	true,	false,
			true,	true,	false,
			true,	false,	false,
		}
	});
		
	/**
	 * El color base de los cuadros para la figura
	 */
	private Color colorBase;
	
	/**
	 * El color de sombreado claro
	 */
	private Color colorClaro;
	
	/**
	 * El color de sombreado oscuro
	 */
	private Color colorOscuro;
	
	/**
	 * Columna inicial para la figura
	 */
	private int columnaInicial;
	
	/**
	 * Fila inicial para la figura
	 */
	private int filaInicial;
	
	/**
	 * La dimension de la figura.
	 */
	private int dimension;
	
	/**
	 * El numero de filas de la figura
	 */
	private int filas;
	
	/**
	 * El numero de columnas de la figura.
	 */
	private int columnas;
	
	/**
	 * Los cuadros que conforman la figura, cada una tiene un array para cada
	 * una de las rotaciones que en total son cuatro
	 */
	private boolean[][] cuadros;
	
	/**
	 * Constructor de la figura
	 * @param color color base de la figura.
	 * @param dimension Dimension del arreglo de cuadros.
	 * @param columnas Numero de columnas.
	 * @param filas Numero de filas.
	 * @param cuadros Los cuadros.
	 */
	private Figura(Color color, int dimension, int columnas, int filas, boolean[][] cuadros) {
		this.colorBase = color;
		this.colorClaro = color.brighter();
		this.colorOscuro = color.darker();
		this.dimension = dimension;
		this.cuadros = cuadros;
		this.columnas = columnas;
		this.filas = filas;
		
		this.columnaInicial = 5 - (dimension >> 1);
		this.filaInicial = obtenerInsercionSuperior(0);
	}
	
	/**
	 * @return el color base.
	 */
	public Color getColorBase() {
		return colorBase;
	}
	
	/**
	 * @return el color claro.
	 */
	public Color getColorClaro() {
		return colorClaro;
	}
	
	/**
	 * @return El color oscuro.
	 */
	public Color getColorOscuro() {
		return colorOscuro;
	}
	
	/**
	 * @return La dimension.
	 */
	public int getDimension() {
		return dimension;
	}
	
	/**
	 * @return La columna inicial.
	 */
	public int getColumnaInicial() {
		return columnaInicial;
	}
	
	/**
	 * @return La fila inicial.
	 */
	public int getFilaInicial() {
		return filaInicial;
	}
	
	/**
	 * @return El numero de filas.
	 */
	public int getFilas() {
		return filas;
	}
	
	/**
	 * @return El numero de columnas.
	 */
	public int getColumnas() {
		return columnas;
	}
	
	/**
	 * Comprueba si las coordenadas de rotacion pintan un cuadro
	 * @param x La coordenada en x
	 * @param y La coordenada en y
	 * @param rotacion El numero de rotacion para validar
	 * @return Si  un cuadro se encuentra alli o no
	 */
	public boolean existeCuadro(int x, int y, int rotacion) {
		return cuadros[rotacion][y * dimension + x];
	}
	
	/**
	 * Se obitene el punto de insercion a la izquierda
	 * @param rotacion La rotacion
	 * @return El punto de insercion en la izquierda.
	 */
	public int obtenerInsercionEnIzquierda(int rotacion) {
		/*
		 * Bucle de izquierda a derecha hasta encontrar un cuadro
		 */
		for(int x = 0; x < dimension; x++) {
			for(int y = 0; y < dimension; y++) {
				if(existeCuadro(x, y, rotacion)) {
					return x;
				}
			}
		}
		return -1;
	}
	
	/**
	 * Se obtiene el punto de insercion a la derecha
	 * @param rotacion La rotacion.
	 * @return El punto de insercion en la derecha.
	 */
	public int obtenerInsercionEnDerecha(int rotacion) {
		/*
		 * Bucle de derecha a izquierda hasta encontrar un cuadro
		 */
		for(int x = dimension - 1; x >= 0; x--) {
			for(int y = 0; y < dimension; y++) {
				if(existeCuadro(x, y, rotacion)) {
					return dimension - x;
				}
			}
		}
		return -1;
	}
	
	/**
	 * Se obtiene el punto de insercion superior
	 * @param rotacion La rotacion.
	 * @return El punto de insercion superior.
	 */
	public int obtenerInsercionSuperior(int rotacion) {
		/*
		 * Bucle de arriba a abajo hasta encontrar un cuadro
		 */
		for(int y = 0; y < dimension; y++) {
			for(int x = 0; x < dimension; x++) {
				if(existeCuadro(x, y, rotacion)) {
					return y;
				}
			}
		}
		return -1;
	}
	
	/**
	 * Se obtiene el punto de insercion inferior
	 * @param rotacion La rotacion.
	 * @return El punto de insercion inferior.
	 */
	public int obtenerInsercionInferior(int rotacion) {
		/*
		 * Bucle de abajo a arriba hasta encontrar un cuadro.
		 */
		for(int y = dimension - 1; y >= 0; y--) {
			for(int x = 0; x < dimension; x++) {
				if(existeCuadro(x, y, rotacion)) {
					return dimension - y;
				}
			}
		}
		return -1;
	}
	
}
